Add logic for 1st person mode glitch#82
Conversation
|
From a quick glance, the PR itself looks nice code-wise (even though function name could be shortened to make it look less bloated). On the "game design" aspect, I'm not fond of the change because first person mode is way too powerful to be in logic imo. If it was harmless to the code, I think I'd just say "let's put it just in case people want to play with it", but it complexifies logic considerably in order to pretty much nullify it, which is not a good trade in my opinion. Please note this is only my opinion and @evilwb will most likely have the final word on this, so this doesn't mean it won't get merged. |
|
These are valid concerns. Don't worry, this doesn't ruin any motivation towards trying to enhance the randomizer. |
|
I feel apprehensive about adding something like this to the code base as it currently stands. This is not because this specific change is bad but is more of a big picture issue. I can see two big categories of logic features on the horizon:
I think combat difficulty logic is more pressing out of the two. The change suggested above would likely be a part of a bigger glitch logic feature down the road. Unfortunately, I think there will need to be structural changes to the current code base to allow it to scale with the massive amount of conditional branches these advanced logic features will require. I haven't put a lot of thought into how we'd implement this yet but I think it will become spaghetti fast if not careful. |
Replaced access_rule by vanilla_recommendation and alternative_routes, allowing easier addition of alternative routing
|
I changed the approach concerning the addition of logic. I replaced the
Here's an example of how it looks: At generation, we take the content of This way, I think we could more easily add logic to the checks. |
|
That's an interesting approach, I like the idea to be able to condition routes in a well-constrained and enumeratable way. MAKTAR_PHOTO_BOOTH = LocationData(
21, "Maktar: Photo Booth",
vanilla_requirements=[can_electrolyze],
alternative_routes=[
AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM,
[can_electrolyze],
alternative_checks=[can_heli]
)
]
)I don't like the MAKTAR_PHOTO_BOOTH = LocationData(
21, "Maktar: Photo Booth",
vanilla_requirements=can_electrolyze,
alternative_routes=[
AlternativeRoute(lambda options: options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_MEDIUM,
lambda state, player: can_electrolyze(state, player) or can_heli(state, player)
)
]
)Overall, this is a step in the right direction into finding a way of improving how complex parameterized logic can be made as clear as possible, but I feel like we're not there yet 😉 |
|
I wanted the I realize that the way I made it forces the alternative route in case we have alternative checks. Maybe it's better to make |
|
My inclination would have been to go a different direction. I see two different routes to dealing with things like this and there's been similar situations with other parts of the code in the past. The routes are:
I'm always torn between which is better and suspect it depends on the problem. You've gone with the more data driven approach so far. The pros of the data driven approach are:
The Cons:
The pro/cons are basically reversed for the procedural approach. One other thing that's bothering me is how big I think this offers a simple solution with lots of flexibility for each location with the main downside of some possible code duplication across functions. I'm not necessarily 100% attached to what I've suggested here and have probably overlooked some details but I think it is route that makes a lot of sense in this case. I'm am definitely open to feedback in this. |
|
I was actually thinking the same thing this afternoon while browsing the code: Locations.py would benefit being smaller and have logic extracted to Logic.py. |
|
I completely agree I did as you suggested and created a function for each check that has requirements. As you said, it offers more flexibility, which we might need in the future with more logic implemented. I'm not quite satisfied with the way I'm doing alternative routes with different requirements. But as it is right now, it shouldn't be a problem. |
Logic.py
Outdated
| if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: | ||
| if not can_levitate(state, player): | ||
| return False | ||
| return (can_swingshot(state, player) | ||
| or can_electrolyze(state, player)) |
There was a problem hiding this comment.
Wouldn't something like this be equivalent?
| if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: | |
| if not can_levitate(state, player): | |
| return False | |
| return (can_swingshot(state, player) | |
| or can_electrolyze(state, player)) | |
| if options.allow_first_person_mode_glitch_locations >= FIRST_PERSON_EASY: | |
| return (can_levitate(state, player) | |
| and ( | |
| can_swingshot(state, player) | |
| or can_electrolyze(state, player))) |
There was a problem hiding this comment.
They are equivalent, indeed.
I just wanted to emphasize the need for the Levitator.
I can change it if needed.
|
Overall, very well done. The logic rules end up being easy to read/interpret and the rest of the code stays simple. The duplication in each function is a little annoying but definitely worth it. Here's another question. Is there a meaningful benefit to having an option to enable first person mode instead of just having it always be enabled? |
|
FPM is a single menu option which doesn't change anything beside switching between 3rd person and 1st person. |
|
I would like to test generation on my dev machine after work as a sanity check and give @Dinopony a chance to respond. Assuming nothing else comes up, this should be good to merge soon. |
|
I added it as an option to be able to keep it forbidden since it's pretty broken (e.g. in a racing context). I was completely taken by text decoding & re-encoding and didn't take the time to review it. |
Dinopony
left a comment
There was a problem hiding this comment.
Good work overall, I'm only concerned by the option naming currently and everything else looks good to me.
|
I think it makes sense to rename the option, especially after removing the other one. |
|
All good to me, I'll let @evilwb do a sanity check and merge the PR. |
This PR adds logic allowing progression items to be placed in checks reachable by exploiting 1st person mode glitch.
I added an option for the player to choose between 3 levels of difficulty: easy, medium and hard. 'no' disables the option.
The difference between the three is how difficult I feel the skips are to pull off.
Maybe some skips are easier to do than I think, maybe some are more difficult, maybe I missed some, so some consensus might be needed on that point.
Note: 1st person mode must be enabled for the logic to work.